﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using LitJson;
using NewEditorNS;
using System;
using System.Drawing;
using FairyGUI.UI;
using System.IO;

/// <summary>整排商铺, 包含若干ShopSignVO</summary>
public class ShopModelMono : MonoBehaviour, IJsonData,IMouseCtrl
{
    #region 记录数据
    public string BuildingName;
    List<Vector3> pointList;
    public List<ShopSignVO> ShopSignList;

    #endregion

    #region 计算用值 不保存
    public Vector3 worldCenter;//镜头焦点跳转
    public Vector3 worldNormal;//镜头焦点跳转
    float shopHeight;
    float shopTotalWidth;
    #endregion

    #region 面片transform

    public void Scale(Vector3 dir)
    {
        Vector3 moveDelta;
        if (dir == Vector3.up || dir == Vector3.down)
        {
            moveDelta = dir.GetScaledVector(0.1f);
            pointList[0] = pointList[0] + moveDelta;
            pointList[1] = pointList[1] - moveDelta;
            pointList[2] = pointList[2] - moveDelta;
            pointList[3] = pointList[3] + moveDelta;
        }
        else
        {
            float rotH = SceneManager.Instance.TheCameraCtrl.TheFocusCtrl.RotH / 180f * Mathf.PI;
            moveDelta = SongeUtil.MoveTowards(rotH, dir);
            moveDelta = moveDelta.GetScaledVector(0.1f);
            pointList[0] = pointList[0] + moveDelta;
            pointList[1] = pointList[1] + moveDelta;
            pointList[2] = pointList[2] - moveDelta;
            pointList[3] = pointList[3] - moveDelta;
        }
        CreatePlane(pointList);
        CreateShops();
    }

    public void Move(Vector3 dir)
    {
        Debug.Log("move");
        //transform.position += dir;
        Vector3 moveDelta;
        if (dir == Vector3.up || dir == Vector3.down)
        {
            moveDelta = dir.GetScaledVector(0.1f);
        }
        else
        {
            float rotH = SceneManager.Instance.TheCameraCtrl.TheFocusCtrl.RotH / 180f * Mathf.PI;
            moveDelta = SongeUtil.MoveTowards(rotH, dir);
            moveDelta = moveDelta.GetScaledVector(0.1f);
        }
        for (int i = 0; i < pointList.Count; i++)
        {
            pointList[i] = pointList[i] + moveDelta;
        }
        CreatePlane(pointList);
        CreateShops();
    }

    public void Rotate(Vector3 dir)
    {
        float angle = dir == Vector3.up ? 1 : -1;
        List<GameObject> pointGOList = new List<GameObject>();
        GameObject centerGO = new GameObject();
        centerGO.transform.position = worldCenter;
        Vector3 rotateCenter = Vector3.zero;
        for (int i = 0; i < pointList.Count; i++)
        {
            GameObject pointGO = new GameObject();
            pointGO.transform.position = pointList[i];
            pointGO.transform.parent = centerGO.transform;
            pointGOList.Add(pointGO);
            rotateCenter += pointList[i];
        }

        centerGO.transform.Rotate(new Vector3(0, angle, 0), Space.Self);
        for (int i = 0; i < pointList.Count; i++)
        {
            GameObject pointGO = pointGOList[i];
            pointList[i] = pointGO.transform.position;
        }
        CreatePlane(pointList);

        Destroy(centerGO);
        Destroy(pointGOList[0]);
        Destroy(pointGOList[1]);
        Destroy(pointGOList[2]);
        Destroy(pointGOList[3]);

    }

    #endregion

    public Vector3 GetOrgPos()
    {
        return pointList.TryGetReturnValue(0);
    }


    /// <summary>记录点, 并计算中间数据</summary>
    public void CreatePlane(List<Vector3> _worldPointList)
    {
        //mf = _mf;
        float _height = _worldPointList[1].y - _worldPointList[0].y;
        shopHeight = _height;
        Vector3 heightVec = new Vector3(0, _height, 0);
        pointList = new List<Vector3>();
        pointList.Add(_worldPointList[1] - heightVec);
        pointList.Add(_worldPointList[1]);
        pointList.Add(_worldPointList[2]);
        pointList.Add(_worldPointList[2] - heightVec);

        Vector3 oa = pointList[1] - pointList[0];
        Vector3 ob = pointList[2] - pointList[0];
        worldNormal = Vector3.Cross(oa, ob);
        worldNormal = worldNormal.normalized;

        worldCenter = (_worldPointList[2] + _worldPointList[1]).GetScaledVector(0.5f) - heightVec;
        shopTotalWidth = Vector3.Distance(pointList[0], pointList[3]);
    }

    /// <summary>一件商铺的模型的宽度 创建时赋予</summary>
    public float CellWidth;

    public void SetVisible(bool isVisible)
    {
        if (isVisible)
        {
            CreateShops(false);
        }
        gameObject.SetActive(isVisible);
    }

    public void DestroyShops()
    {
        for (int i = 0, length = transform.childCount; i < length; i++)
        {

            Material[] matArr = transform.GetChild(i).GetComponentInChildren<Renderer>().materials;
            for (int matIndex = 0, matNum = matArr.Length; matIndex < matNum; matIndex++)
            {
                Destroy(matArr[matIndex]);
            }
            Destroy(transform.GetChild(i).gameObject);
        }
    }

    bool _isShopCreated = false;
    /// <summary>创建商铺模型, 并加载招牌/铺面贴图</summary>
    public void CreateShops(bool isForceCreate = true)
    {
        if (!isForceCreate)
        {
            if (_isShopCreated)
            {
                return;
            }
        }
        Debug.Log("CreateShops");
        DestroyShops();
        //Resources.UnloadUnusedAssets();

        if (ShopSignList == null)
            ShopSignList = new List<ShopSignVO>();

        float curCellWidth = 0;
        for (int iSS = 0, lenSS = ShopSignList.Count; iSS < lenSS; iSS++)
        {
            ShopSignVO ss = ShopSignList[iSS];

            GameObject shop = ShopEditor.Instance.CreateShopModel(ss.CellNum, ss.PrefabType);
            shop.transform.parent = transform;
            shop.transform.localEulerAngles = new Vector3(-90, 0, 0);
            shop.transform.localPosition = new Vector3(-curCellWidth, 0, 0);
            shop.transform.localScale = new Vector3(1, 1, shopHeight / 3.35f);
            SongeUtil.forAllChildren(shop, child =>
            {
                if (child.GetComponent<MeshFilter>() != null)
                {
                    child.AddComponent<MeshCollider>();
                }
            });


            curCellWidth += CellWidth * ss.CellNum;
            Debug.Log("Material[] matArr = shop.GetCo");
            Material[] matArr = shop.GetComponentInChildren<Renderer>().materials;
            Material matShop = matArr.FindItem(mat => { return mat.name.Contains("mat_context"); });
            Material matSign = matArr.FindItem(mat => { return mat.name.Contains("mat_zp"); });



            //ShopSignEditor.instance.GetSignTexByCode(ss.SignCode, tex =>
            //{
            //    if (this != null && tex != null && matSign != null)
            //        matSign.mainTexture = tex;
            //});
            //ShopSignEditor.instance.GetShopTexByCode(ss.ShopCode, ss.CellNum, tex =>
            //{
            //    if (this != null && tex != null && matShop != null)
            //        matShop.mainTexture = tex;
            //});

            RoteAreaData data = MonoHelper.Instance.GetRouteDataById(ShopEditor.PreFix_RouteID + ss.RouteID);

            if (data != null)
            {
                Texture txSign = null;
                if (data.IsLocal)
                {
                    txSign = ss.GetSignTextrue();
                }
                else
                {
                    txSign = ss.GetSignTextrue(data.m_ab);
                }
                
                bool flag = (this != null) && (txSign != null) && (matSign != null);
                if (flag)
                {
                    matSign.mainTexture = txSign;
                }
            }
            else
            {
                Debug.Log("ss.RouteID: " + ss.RouteID);
                throw new Exception("获取图片失败");
            }

            if (!UtilsCommonS.IsStringNullOrEmptyOrDefault(ss.ShopCode))
            {
                Texture txShop = MonoHelper.Instance.GetShopTextureByCode(ss.ShopCode, ss.CellNum);
                if (this != null && txShop != null && matShop != null)
                {
                    matShop.mainTexture = txShop;
                }
                Debug.Log("Texture txShop = MonoHelper.Instance.GetShopTe");
            }

        }
        transform.localScale = new Vector3(curCellWidth == 0 ? 1 : shopTotalWidth / curCellWidth, 1, 1);
        transform.eulerAngles = Vector3.up.GetScaledVector(SongeUtil.GetRotateY(worldNormal));
        transform.position = pointList[0] + worldNormal.normalized.GetScaledVector(0.1f);
        Debug.Log("CreateShops ends");
        _isShopCreated = true;
    }

    public void setChildVisible(bool flag)
    {
        SongeUtil.forAllChildren(gameObject, tar => { tar.SetActive(flag); }, false);
    }
    #region MouseCtrl

    public void MouseDown(Vector2 screenPoint, Vector3 worldPoint, int mouse)
    {
        //throw new System.NotImplementedException();
    }

    public void MouseUp(Vector2 screenPoint, Vector3 worldPoint, int mouse)
    {
        //throw new System.NotImplementedException();
    }

    public void MouseClick(Vector2 screenPoint, Vector3 worldPoint, int mouse)
    {
        //throw new System.NotImplementedException();

    }

    public void MouseDoubleClick(Vector2 screenPoint, Vector3 worldPoint, int mouse)
    {
        //throw new System.NotImplementedException();
    }

    public void OnDragStart(Vector2 screenPoint, Vector3 worldPoint, int mouse)
    {
        //throw new System.NotImplementedException();
    }

    public void OnDraging(Vector2 screenPoint, Vector3 worldPoint, int mouse)
    {
        //throw new System.NotImplementedException();
    }

    public void OnDragEnd(Vector2 screenPoint, Vector3 worldPoint, int mouse)
    {
        //throw new System.NotImplementedException();
    }
    #endregion

    #region JsonData

    public string GetLabelText()
    {
        return BuildingName;
    }

    public void UpdateSignCrc(Dictionary<string, string> dicMap)
    {
        for (int i = 0; i < ShopSignList.Count; i++)
        {
            var voSign = ShopSignList[i];
            if (!dicMap.ContainsKey(voSign.SignCode))
            {
                Debug.Log("配置文件缺项 " + voSign.SignCode);
                continue;
            }
            voSign.SignCrc = dicMap.TryGetReturnValue(voSign.SignCode);
        }
    }

    public void SetSignRouteID(string routeID)
    {
        for (int i = 0; i < ShopSignList.Count; i++)
        {
            var item = ShopSignList[i];
            if (!UtilsCommonS.IsStringNullOrEmptyOrDefault(item.RouteID))
            {
                if (item.RouteID != routeID)
                {
                    Debug.LogError("招牌走向图配置错误!");
                }
            }
            else
            {
                item.RouteID = routeID;
            }
        }
    }

    public JsonData ToJsonData()
    {
        JsonData jd = new JsonData();

        jd["buildName"] = BuildingName;
        List<string> dataList = pointList.ConvertAll<string>((vec) => { return JsonUtils.vecToStr(vec); });
        jd["pointList"] = JsonUtils.ToJsonData(dataList);
        if (ShopSignList != null)
            jd["shopSignList"] = ShopSignList.ToJsonDataList<ShopSignVO>();
        return jd;
    }

    public IJsonData ReadJsonData(JsonData jd)
    {
        if (jd.Keys.Contains("buildName"))
            BuildingName = jd["buildName"].ToString();
        if (jd.Keys.Contains("pointList"))
            pointList = jd["pointList"].ToVec3List();
        if (jd.Keys.Contains("shopSignList"))
            ShopSignList = jd["shopSignList"].ToItemVOList<ShopSignVO>();
        return this;
    }

    bool isSelected;
    public bool IsSelect
    {
        get
        {
            return isSelected;
        }
        set
        {
            isSelected = value;
            if(onDataChange != null)
                onDataChange();
        }
    }
    #endregion

    Action onDataChange;
    public Action OnDataChange
    {
        get
        {
            return onDataChange;
        }
        set
        {
            onDataChange = value;
        }
    }
}



public class ShopSignVO : IJsonData
{
    public static string PrefabTypeShopSign = "ShopSign";
    public static string PrefabTypeOnlyShop = "OnlyShop";
    public static string PrefabTypeOnlySign = "OnlySign";

    public static string SignType_Normal = "SighType_Nomal";
    public static string SignType_Text = "SighType_Text";

    public Action onDataChange;

    /// <summary>走向图ID TODO 在创建时赋予</summary>
    public string RouteID = "";

    public int CellNum = 1;//间数
    public string ShopName;//商铺名称
    public string ShopCode;//铺面贴图代码
    //public string SignCode;//招牌贴图代码
    public string _signCode;
    public string SignCode { get { return _signCode; } }

    public string SignCrc;
    public string PrefabType = "ShopSign";//商铺模型类型
    public string ShopID;//ID
    public string SignType = /*SignType_Text*/SignType_Normal;
    public string SignText = "我是招牌";
    const string DefaultPicExt = ".jpg";

    public bool IsSignText
    {
        private set { }
        get { return SignType == SignType_Text; }
    }

    public ShopSignVO()
    {
    }

    public ShopSignVO(int cellNum)
    {
        this.CellNum = cellNum;
    }

    public void SetSignCode(string code)
    {
        if (string.IsNullOrEmpty(code))
        {
            _signCode = code;
            return;
        }
        string ext = Path.GetExtension(code);
        if (string.IsNullOrEmpty(ext))
        {
            code = code + DefaultPicExt;
        }
        else
        {
            var lowerExt = ext.ToLower();
            if (ext != lowerExt)
            {
                Path.ChangeExtension(code, lowerExt);
            }
        }
        _signCode = code;
    }

    public JsonData ToJsonData()
    {
        JsonData jd = new JsonData();
        jd["CellNum"] = CellNum;
        jd["ShopName"] = ShopName;
        jd["ShopCode"] = ShopCode;
        jd["SignCode"] = SignCode;
        jd["SignCrc"] = SignCrc;
        jd["PrefabType"] = PrefabType.ToString();
        jd["ShopID"] = ShopID;
        jd["RouteID"] = RouteID;
        jd["SighType"] = SignType;
        jd["SighText"] = SignText;
        return jd;
    }

    public IJsonData ReadJsonData(JsonData jd)
    {
        CellNum = jd.ReadInt("CellNum");

        ShopName = jd.ReadString("ShopName");
        ShopCode = jd.ReadString("ShopCode");
        SetSignCode(jd.ReadString("SignCode"));
        SignCrc = jd.ReadString("SignCrc");
        PrefabType = jd.ReadString("PrefabType", "");
        ShopID = jd.ReadString("ShopID");
        RouteID = jd.ReadString("RouteID", "");
        SignType = jd.ReadString("SighType", SignType_Normal);
        SignText = jd.ReadString("SighText", ShopName);
        return this;
    }

    public Texture GetSignTextrue(AssetBundle ab)
    {
        var ret = GetSignText();
        if (null == ret)
        {
            if (null == ab)
            {
                return null;
            }
            return MonoHelper.Instance.GetTexAsset(ab, SignCode);
        }
        return ret;
    }

    public Texture GetSignTextrue()
    {
        var ret = GetSignText();
        if (null == ret)
        {
            var fileBytes = GetSignBytes();
            if (fileBytes != null)
            {
                return UtilsCommonS.ByteArrayToTexture(fileBytes);
            }
        }

        if (ret == null)
        {
            Debug.LogWarning("加载商铺图片" + SignCode + "失败");
            return MonoHelper.Instance.m_failTex;
        }

        return null;
    }

    public byte[] GetSignNameCrc(out string name, out string crc)
    {
        name = crc = string.Empty;
        var filebuf = GetSignBytes();
        if (filebuf != null)
        {
            name = SignCode;
            crc = Crc32.CountCrcRetString(filebuf);
        }
        return filebuf;
    }

    public byte[] GetSignBytes()
    {
        RoteAreaData routeData = MonoHelper.Instance.GetRouteShopDataByPureID(RouteID);
        if (routeData != null)
        {
            var fileInfo = routeData.GetLocalFileInfo(SignCode);
            if (fileInfo != null)
            {
                return UtilsCommonS.LoadFile(fileInfo.FullName);
            }
        }
        return null;
    }


    Texture GetSignText()
    {
        if (IsSignText)
        {
            Bitmap bmp = UtilsCommon.Instance.TextToBitmapAllDefault(SignText);
            return UtilsCommonS.ImageToTexture2D(bmp, true);
        }
        else
        {
            return null;
        }
    }
}